<?php

class Lemar_Calendar
{
	/**
	 *
	 * @var integer day in the week
	 */
	const DAYS_PER_WEEK = 7;
	
//---------------------------------------------------------------------------------------------------------------------------
		
	/**
	 *
	 * @var integer number of weeks to display
	 */
	const NUMBER_OF_WEEKS = 6;
	
//---------------------------------------------------------------------------------------------------------------------------
		
	/**
	 * Get data to Month view
	 *
	 * @var integer $sWeekFirstDay 0 - Sunday, 1 - Monday
	 * @var integer $iMonth 1 - Jun, 12 - Dec
	 * @return array
	 */
	public static function getCalendar($sWeekFirstDay=1, $iMonth=0, $iYear=0)
	{
		$aDayNamesMon = array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun');
		$aDayNamesSun = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');

		$iYear  = (int) (($iYear !== 0) ? $iYear : date('Y'));
		$iMonth = (int) (($iMonth !== 0) ? $iMonth : date('m'));

		// timestamp of the first day of the month
		$iFirstDayTS = mktime(0, 0, 0, $iMonth, 1, $iYear);

		// number of days in the current month
		$iDaysNumber = date('t', $iFirstDayTS);
		$iTS = mktime(0, 0, 0, $iMonth-1, 1, $iYear);
		$sMonthPrev = date('F', $iTS);

		// number of days in the previous month
		$iDaysNumberPrev = date('t', $iFirstDayTS-1);
		$iTS = mktime(0, 0, 0, $iMonth+1, 1, $iYear);
		$sMonthNext = date('F', $iTS);

		// 0 (Sunday) - 6 (Saturday), or 0 (Monday) - 6 (Sunday)
		$iFirstDay = date('w', $iFirstDayTS);

		if (0 == $sWeekFirstDay)
		{
			$aDayNames = $aDayNamesSun;
		}
		else
		{
			$aDayNames = $aDayNamesMon;
			if (0 == $iFirstDay)
			{
				$iFirstDay = 6;
			}
			else
			{
				$iFirstDay--;
			}
		}

		$iSelectDay = self::getSelectDay($iMonth, $iYear);
		$aCurrentDay = 1;
		$aWeeks = array();
		//		$aAppointmentToMonth = self::_getDataToPeriod($iFirstDayTS, $iTS);
		$aTasksAndAppToMonth = self::_getDataToPeriod($iFirstDayTS, $iTS);
		$aAppointmentToMonth = $aTasksAndAppToMonth[0];
		$aTasksToMonth = $aTasksAndAppToMonth[1];

		for ($iWeek=0; $iWeek < self::NUMBER_OF_WEEKS; $iWeek++)
		{
			$aDays = array();
			for ($iDay=0; $iDay < self::DAYS_PER_WEEK; $iDay++)
			{
				if ($iDay < $iFirstDay && 0 == $iWeek)
				{
					// add a day from the previous month
					$aDays[$iDay]['daynumber'] = $sMonthPrev." ".($iDaysNumberPrev - $iFirstDay + $iDay + 1);
				}
				elseif ($aCurrentDay > $iDaysNumber)
				{
					// add a day from the next month
					$aDays[$iDay]['daynumber'] = $sMonthNext." ".($aCurrentDay++ - $iDaysNumber);
				}
				else
				{
					$aDays[$iDay]['daynumber'] = $aCurrentDay++;
					if( self::isDayOff($iMonth, $aDays[$iDay]['daynumber'], $iYear) )
					{
						$aDays[$iDay]['dayoff'] = true;
					}
					if( $aDays[$iDay]['daynumber'] == $iSelectDay )
					{
						$aDays[$iDay]['select'] = true;
					}
					if( isset($aAppointmentToMonth[$aDays[$iDay]['daynumber']]) )
					{
						$aDays[$iDay]['app'] = $aAppointmentToMonth[$aDays[$iDay]['daynumber']];
					}
					if( isset($aTasksToMonth[$aDays[$iDay]['daynumber']]) )
					{
						$aDays[$iDay]['task'] = $aTasksToMonth[$aDays[$iDay]['daynumber']];
					}
				}
			}
			$aWeeks[] = $aDays;
		}

		$aReturn['year'] = $iYear;
		$aReturn['month'] = $iMonth;
		$aReturn['dayNames'] = $aDayNames;
		$aReturn['weeks'] = $aWeeks;
		$aReturn['top'] = date('F', $iFirstDayTS)." '".date('y', $iFirstDayTS);

		return $aReturn;
	}
	
//---------------------------------------------------------------------------------------------------------------------------
		
	/**
	 * Get numbers years
	 *
	 * @return array - numbers of year
	 */
	public static function getYears()
	{
		$aDateYear = array();
		$sYear = date('Y');
		$dev = 10;
		$aDateYear[$dev] = $sYear;
		for ($i = $dev; $i > 0; $i--)
		{
//			$aDateYear[$dev - $i] = $sYear - $i;
			$aDateYear[$dev + $i] = $sYear + $i;
		}
		sort($aDateYear);
		/*$aDateYear[0] = $sYear - 2;
		$aDateYear[1] = $sYear - 1;
		$aDateYear[2] = $sYear;
		$aDateYear[3] = $sYear + 1;
		$aDateYear[4] = $sYear + 2;*/

		return $aDateYear;
	}
	
//---------------------------------------------------------------------------------------------------------------------------
		
	/**
	 * define dayoff
	 *
	 * @var integer $iMonth - month
	 * @var integer $iDay - day of the month
	 * @var integer $iYear - year
	 * @return bool true|false
	 */
	public static function isDayOff($iMonth, $iDay, $iYear)
	{
		$iDayTS = mktime(0, 0, 0, $iMonth, $iDay, $iYear);
		$sDayName = date('l', $iDayTS);
		if($sDayName == 'Sunday' || $sDayName == 'Saturday')
		{
			return true;
		}
		return false;
	}
	
//---------------------------------------------------------------------------------------------------------------------------
		
	/**
	 * define select day
	 *
	 * @var integer $iMonth - month
	 * @var integer $iYear - year
	 * @return integer
	 */
	public static function getSelectDay($iMonth, $iYear)
	{
		$iDateTS = mktime(0, 0, 0, $iMonth, 1, $iYear);
		if( date('Y m', $iDateTS) == date('Y m') )
		{
			return date('j');
		}
		return 0;
	}
	
//---------------------------------------------------------------------------------------------------------------------------
		
	/**
	 * get data to period between two date
	 *
	 * @var integer $iFirstDayTS - first day time stamp
	 * @var integer $iLastDayTS - last day time stamp
	 * @return associative array
	 */
	private static function _getDataToPeriod($iFirstDayTS, $iLastDayTS)
	{
//		return array('', '');
		$sFirstDate = date('Y-m-d', $iFirstDayTS);
		$sLastDate = date('Y-m-d', $iLastDayTS);

//		$aAppointment = models_AppointmentMapper::findByIdWeddingAndDate($oWedding->getId(), $sFirstDate, $sLastDate);
		$aTasks = models_EventMapper::findByIdUserAndDate(Lemar_User::getLoggedUserId(), $sFirstDate, $sLastDate);

		$aAppointmentToMonth = array();
//		foreach($aAppointment as $oAppointment)
//		{
//			$aDate = explode('-', $oAppointment->getDay() );
//			$iDay = (int) end($aDate);
//			$aAppointmentToMonth[$iDay][] = $oAppointment;
//		}

		$aTaskToMonth = array();
		foreach($aTasks as $aTask)
		{
			$aDate = explode('-', $aTask['date']);
			$iDay = (int) end($aDate);
			$aTaskToMonth[$iDay][] = $aTask;
		}
		$aRet = array($aAppointmentToMonth, $aTaskToMonth);
		//        return $aAppointmentToMonth;
		return $aRet;
	}
	
//---------------------------------------------------------------------------------------------------------------------------
		
	/**
	 *  Calendar controller index action
	 *
	 * @var object $oRequest http request
	 * @return array
	 */
	public static function indexCalendar($oRequest)
	{
		$oForm = new modules_default_forms_CalendarForm();
		if( $oForm->isValid($oRequest->getQuery()) )
		{
			return self::getCalendar(1, $oForm->getValue('month'), $oForm->getValue('year') );
		}
		else
		{
			return self::getCalendar(1);
		}
	}
	
//---------------------------------------------------------------------------------------------------------------------------
		
	/**
	 *  Calendar controller save action
	 *
	 * @var Zend_Controller_Request_Abstract $oRequest
	 * @var models_Wedding $oWedding
	 * @return array
	 */
	public static function saveAppointmentToCalendar(Zend_Controller_Request_Abstract $oRequest, models_Wedding $oWedding)
	{
		$data = array();
		if($oRequest->isPost())
		{
			$oForm = new forms_CalendarDateForm();
			if($oForm->isValid($oRequest->getPost()))
			{
				if( '' != $oForm->getValue('id') )
				{
					$oAppointment = models_AppointmentMapper::findById($oForm->getValue('id'));
					if( $oAppointment->getIdWedding() == $oWedding->getId() )
					{
						$oAppointment->setId($oForm->getValue('id'));

						$iTS = mktime(0,0,0, $oForm->getValue('month'), $oForm->getValue('day'), $oForm->getValue('year'));

						$oAppointment->setDay(date('Y-m-d', $iTS));
						$oAppointment->setDayTime(date('h:i:s', $iTS));
						$oAppointment->setText($oForm->getValue('text'));

						if(models_AppointmentMapper::save($oAppointment))
						{
							$data['result'] = true;
							$data['action'] = 'update';
							$data['iId'] = $oForm->getValue('id');

						}
						else
						{
							$data['result'] = false;
						}
					}
					else
					{
						$data['result'] = false;
					}
				}
				else
				{
					$oAppointment = new models_Appointment();
					$iTS = mktime(0,0,0, $oForm->getValue('month'), $oForm->getValue('day'), $oForm->getValue('year'));
					$oAppointment->setDay(date('Y-m-d', $iTS));
					$oAppointment->setDayTime(date('h:i:s', $iTS));
					$oAppointment->setIdWedding($oWedding->getId());
					$oAppointment->setText($oForm->getValue('text'));

					$iId = models_AppointmentMapper::save($oAppointment);
					if($iId)
					{
						$data['result'] = true;
						$data['action'] = 'create';
						$data['iId'] = $iId;
					}
				}
			}
			else
			{
				$data['result'] = false;
			}
		}
		else
		{
			$data['redirect'] = true;
		}
		return $data;
	}
	
//---------------------------------------------------------------------------------------------------------------------------
		
	/**
	 *  Calendar controller delete action
	 *
	 * @var Zend_Controller_Request_Abstract $oRequest
	 * @var models_Wedding $oWedding
	 * @return array
	 */
	public static function deleteAppointmentFromCalendar(Zend_Controller_Request_Abstract $oRequest, models_Wedding $oWedding)
	{
		$data = array();
		if($oRequest->isPost())
		{
			$oZVDigits = new Zend_Validate_Digits();
			if($oZVDigits->isValid($oRequest->getPost('id')) &&
			models_AppointmentMapper::deleteByIdAndIdWedding($oRequest->getPost('id'), $oWedding->getId()) )
			{
				$data['result'] = true;
				$data['iId'] = $oRequest->getPost('id');
			}
		}
		else
		{
			$data['redirect'] = true;
		}
		return $data;
	}
	
//---------------------------------------------------------------------------------------------------------------------------
		
	/**
	 * Gets appointments to the next days
	 *
	 * @param int $iDays - next days from current date
	 * @return array
	 */
	public static function getAppointmentToDays($iDays, models_Wedding $oWedding)
	{
		$iFirstDayTS = time();
		$iLastDayTS = $iFirstDayTS+(60*60*24*$iDays);

		$sFirstDate = date('Y-m-d', $iFirstDayTS);
		$sLastDate = date('Y-m-d', $iLastDayTS);

		$aAppointment = models_AppointmentMapper::findByIdWeddingAndDate($oWedding->getId(), $sFirstDate, $sLastDate);
		return $aAppointment;
	}
	
//---------------------------------------------------------------------------------------------------------------------------
	
}